package com.lfc.DuLaiDuWang.utils.download

import com.leifu.mvpkotlin.net.rx.RetrofitManager
import com.lfc.myframe.share.Const
import com.lfc.myframe.utils.download.DownloadCallBack
import com.lfc.myframe.utils.download.SPDownloadUtil
import com.tamsiree.rxkit.TLog
import io.reactivex.Observer
import io.reactivex.disposables.Disposable
import okhttp3.ResponseBody
import java.io.File
import java.io.InputStream
import java.io.RandomAccessFile

/**
 * Created by LFC
on 2020/5/15.
 */
class DownloadAPi {
    companion object {
        fun downloadFile(
            range: Long,
            url: String,
            fileName: String,
            downloadCallback: DownloadCallBack
        ) {
            //断点续传时请求的总长度
            val file = File(Const.Data_FileDirPath, fileName)
            var totalLength = "-"
            if (file.exists()) {
                totalLength += file.length()
            }

            RetrofitManager.apiService.downloadFile(
                "bytes=" + java.lang.Long.toString(range) + totalLength,
                url
            )
//                .subscribeOn(Schedulers.io())
//                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(object : Observer<ResponseBody> {

                    override fun onSubscribe(d: Disposable) {

                    }

                    override fun onNext(responseBody: ResponseBody) {
                        var randomAccessFile: RandomAccessFile? = null
                        var inputStream: InputStream? = null
                        var total = range
                        var responseLength: Long = 0
                        try {
                            val buf = ByteArray(2048)
                            var len = 0
                            responseLength = responseBody.contentLength()
                            inputStream = responseBody.byteStream()
                            val filePath = Const.Data_FileDirPath
                            val file = File(filePath, fileName)
                            val dir = File(filePath)
                            if (!dir.exists()) {
                                dir.mkdirs()
                            }
                            randomAccessFile = RandomAccessFile(file, "rwd")
                            if (range == 0L) {
                                randomAccessFile!!.setLength(responseLength)
                            }
                            randomAccessFile!!.seek(range)

                            var progress = 0
                            var lastProgress = 0
                            downloadCallback.onPrepare(responseLength, "")

//                                while ((len = inputStream?.read(buf)) != -1) {
                            while (inputStream?.read(buf)?.also { len = it } != -1) {
                                randomAccessFile.write(buf, 0, len)
                                total += len.toLong()
                                SPDownloadUtil.getInstance().save(url, total)
                                lastProgress = progress
                                progress = (total * 100 / randomAccessFile.length()).toInt()
                                if (progress > 0 && progress != lastProgress) {
                                    downloadCallback.onProgress(progress)
                                }
                            }

                            downloadCallback.onCompleted()
                        } catch (e: Exception) {
                            TLog.d(e.message.toString())
                            downloadCallback.onError(e.message)
                            e.printStackTrace()
                        } finally {
                            try {
                                if (randomAccessFile != null) {
                                    randomAccessFile.close()
                                }

                                if (inputStream != null) {
                                    inputStream.close()
                                }

                            } catch (e: Exception) {
                                e.printStackTrace()
                            }

                        }
                    }

                    override fun onError(e: Throwable) {
                        downloadCallback.onError(e.toString())
                    }

                    override fun onComplete() {}
                })
        }

    }
}